Listing C-1 shows a simple but complete application program illustrating the use of QuickTime on the Windows platform. The program uses the Windows single document interface (SDI) to present a movie on the screen, allowing the user to control its display by manipulating a standard movie controller with the mouse. The program also supports basic operations such as file saving and simple cut-and-paste editing. The code shown here is adapted from one of the sample programs provided as part of the QuickTime 3 Software Development Kit for Windows.
Listing C-1 Simple movie player
///////////////////////////////////////////////////////////////////////////////////////
//
// SimpleEditSDI
// Written by Keith Gurganus
//
// A single-document-interface (SDI) application that plays a movie with QuickTime.
// This program is part of the QuickTime sample source code and is provided as is.
//
// Copyright:© 1997 by Apple Computer, Inc., all rights reserved.
//
///////////////////////////////////////////////////////////////////////////////////////
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <windows.h>
#include "QTML.h"
#include "Movies.h"
// Resource identifiers
#define IDM_NEW 100
#define IDM_OPEN 101
#define IDM_SAVE 102
#define IDM_SAVEAS 103
#define IDM_PRINT 104
#define IDM_PRINTSETUP 105
#define IDM_EXIT 106
#define IDM_UNDO 200
#define IDM_CUT 201
#define IDM_COPY 202
#define IDM_PASTE 203
#define IDM_LINK 204
#define IDM_LINKS 205
#define IDM_HELPCONTENTS 300
#define IDM_HELPSEARCH 301
#define IDM_HELPHELP 302
#define IDM_ABOUT 303
#define IDM_HELPTOPICS 304
#define IDC_STATIC -1
#define DLG_VERFIRST 400
#define IDC_COMPANY DLG_VERFIRST
#define IDC_FILEDESC DLG_VERFIRST+1
#define IDC_PRODVER DLG_VERFIRST+2
#define IDC_COPYRIGHT DLG_VERFIRST+3
#define IDC_OSVERSION DLG_VERFIRST+4
#define IDC_TRADEMARK DLG_VERFIRST+5
#define DLG_VERLAST DLG_VERFIRST+5
#define IDC_LABEL DLG_VERLAST+1
#define IDR_ACCELSIMPLESDI 128
#define IDR_SIMPLESDI 128
#define IDR_SMALL 129
#define IDR_WIN95 131
#define IDD_ABOUTBOX 132
#define IDI_BIG 139
#define APPNAME 'SimpleEditSDI'
// Macros to determine appropriate code paths
#if defined (WIN32)
#define IS_WIN32 TRUE
#else
#define IS_WIN32 FALSE
#endif
#define IS_NT IS_WIN32 && (BOOL)(GetVersion() < 0x80000000)
#define IS_WIN32S IS_WIN32 && (BOOL)(!(IS_NT) && (LOBYTE(LOWORD(GetVersion()))<4))
#define IS_WIN95 (BOOL)(!(IS_NT) && !(IS_WIN32S)) && IS_WIN32
// Data type
typedef struct
{
char filename[255];
Movie theMovie;
MovieController theMC;
Boolean movieOpened;
HWND theHwnd;
} MovieStuff;
// Global variables
HINSTANCE hInst; // Current instance
char szAppName[] = APPNAME; // Name of this application
char szTitle[] = APPNAME; // Title bar text
MovieStuff gMovieStuff; // Movie structure
// Function prototypes
BOOL
InitApplication
(HINSTANCE hInstance);
ATOM
MyRegisterClass
(CONST WNDCLASS *lpwc);
BOOL
InitInstance
(HINSTANCE hInstance,
int nCmdShow);
LRESULT CALLBACK
WndProc
(HWND hWnd,
UINT message,
WPARAM wParam,
LPARAM lParam);
LRESULT CALLBACK
About
(HWND hDlg,
UINT message,
WPARAM wParam,
LPARAM lParam);
BOOL
GetFile
(char *fileName);
static UINT APIENTRY
GenericHook
(HWND hWnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam);
BOOL
OpenMovie
(HWND hwnd,
MovieStuff *movieStuff);
void
CreateNewMovieController
(HWND hwnd,
Movie theMovie,
MovieController *theMC);
Boolean
MCFilter
(MovieController mc,
short action,
void *params,
long refCon);
void
GetMaxBounds
(Rect *maxRect);
void
SetWindowTitle
(HWND hWnd,
unsigned char *theFullPath);
void
GetFileNameFromFullPath
(unsigned char *theFullPath,
unsigned char *fileName);
void
CloseMovie
(MovieStuff *movieStuff);
OSErr
SaveMovie
(MovieStuff *movieStuff);
OSErr
SaveAsMovie
(MovieStuff *movieStuff);
ComponentResult
EditUndo
(MovieController mc);
ComponentResult
EditCut
(MovieController mc);
ComponentResult
EditCopy
(MovieController mc);
ComponentResult
EditPaste
(MovieController mc);
ComponentResult
EditClear
(MovieController mc);
ComponentResult
EditSelectAll
(Movie movie,
MovieController mc);
void
UpdateMenus
(MovieStuff movieStuff);
///////////////////////////////////////////////////////////////////////////////////////
//
// WinMain
//
///////////////////////////////////////////////////////////////////////////////////////
int CALLBACK
WinMain
(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
MSG msg;
HANDLE hAccelTable;
if ( !hPrevInstance )
// Perform instance initialization.
if ( !InitApplication(hInstance) )
return FALSE;
// Initialize QuickTime Media Layer.
InitializeQTML(0);
// Initialize QuickTime.
EnterMovies();
// Perform application initialization.
if ( !InitInstance(hInstance, nCmdShow) )
return FALSE;
// Load accelerator table.
hAccelTable = LoadAccelerators (hInstance,
MAKEINTRESOURCE(IDR_ACCELSIMPLESDI));
// Main message loop:
while (GetMessage(&msg, NULL, 0, 0))
if ( !TranslateAccelerator(msg.hwnd, hAccelTable, &msg) )
{
TranslateMessage(&msg);
DispatchMessage(&msg);
} /* end if */
// Terminate QuickTime.
ExitMovies();
// Terminate QuickTime Media Layer.
TerminateQTML();
return msg.wParam;
// The following line is included to prevent
// 'unused formal parameter' warnings.
lpCmdLine;
} /* end WinMain */
///////////////////////////////////////////////////////////////////////////////////////
//
// InitApplication
//
///////////////////////////////////////////////////////////////////////////////////////
BOOL
InitApplication
(HINSTANCE hInstance)
{
WNDCLASS wc;
HWND hwnd;
// Win32 will always set hPrevInstance to NULL. We only want a single version
// of this app to run at a time, so let's check things a little closer.
hwnd = FindWindow (szAppName, NULL);
if ( hwnd )
// We found another instance of ourself. Let's defer to it:
{
if ( IsIconic(hwnd) )
ShowWindow(hwnd, SW_RESTORE);
SetForegroundWindow (hwnd);
return FALSE;
} /* end if ( hwnd ) */
// Fill in window class structure with parameters that describe
// the main window.
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC)WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon (hInstance, MAKEINTRESOURCE(IDI_BIG));
wc.hCursor = LoadCursor (NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.lpszMenuName = MAKEINTRESOURCE(IDR_SIMPLESDI);
wc.lpszClassName = szAppName;
// Register the window class and return success/failure code.
if (IS_WIN95)
return MyRegisterClass(&wc);
else
return RegisterClass(&wc);
} /* end InitApplication */
///////////////////////////////////////////////////////////////////////////////////////
//
// MyRegisterClass
//
///////////////////////////////////////////////////////////////////////////////////////
ATOM
MyRegisterClass
(CONST WNDCLASS *lpwc)
{
HANDLE hMod;
FARPROC proc;
WNDCLASSEX wcex;
hMod = GetModuleHandle ("USER32");
if ( hMod != NULL )
{
#if defined (UNICODE)
proc = GetProcAddress (hMod, "RegisterClassExW");
#else
proc = GetProcAddress (hMod, "RegisterClassExA");
#endif
if ( proc != NULL )
{
// Copy elements from WNDCLASS structure.
wcex.style = lpwc->style;
wcex.lpfnWndProc = lpwc->lpfnWndProc;
wcex.cbClsExtra = lpwc->cbClsExtra;
wcex.cbWndExtra = lpwc->cbWndExtra;
wcex.hInstance = lpwc->hInstance;
wcex.hIcon = lpwc->hIcon;
wcex.hCursor = lpwc->hCursor;
wcex.hbrBackground = lpwc->hbrBackground;
wcex.lpszMenuName = lpwc->lpszMenuName;
wcex.lpszClassName = lpwc->lpszClassName;
// Add extra elements for Windows 95.
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.hIconSm = LoadIcon(wcex.hInstance,
MAKEINTRESOURCE(IDR_SMALL));
// Return RegisterClassEx(&wcex).
return (*proc)(&wcex);
} /* end if ( proc != NULL ) */
} /* end if ( hMod != NULL ) */
return RegisterClass(lpwc);
} /* end MyRegisterClass */
///////////////////////////////////////////////////////////////////////////////////////
//
// InitInstance
//
///////////////////////////////////////////////////////////////////////////////////////
BOOL
InitInstance
(HINSTANCE hInstance,
int nCmdShow)
{
HWND hWnd;
// Store instance handle in our global variable.
hInst = hInstance;
// Create our window.
hWnd = CreateWindow(szAppName,
szTitle,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0,
CW_USEDEFAULT, 0,
NULL,
NULL,
hInstance,
NULL);
if ( !hWnd )
return FALSE;
ShowWindow (hWnd, nCmdShow);
UpdateWindow (hWnd);
return TRUE;
} /* end InitInstance */
///////////////////////////////////////////////////////////////////////////////////////
//
// WndProc
//
///////////////////////////////////////////////////////////////////////////////////////
LRESULT CALLBACK
WndProc
(HWND hWnd,
UINT message,
WPARAM wParam,
LPARAM lParam)
{
int wmId, wmEvent;
PAINTSTRUCT ps;
HDC hdc;
if ( Hwnd2Wptr(hWnd) )
{
MSG msg;
EventRecord macEvent;
LONG thePoints = GetMessagePos();
msg.hwnd = hWnd;
msg.message = message;
msg.wParam = wParam;
msg.lParam = lParam;
msg.time = GetMessageTime();
msg.pt.x = LOWORD(thePoints);
msg.pt.y = HIWORD(thePoints);
// Convert the message to a QTML event.
NativeEventToMacEvent (&msg, &macEvent);
// If we have a movie controller, pass the QTML event.
if ( gMovieStuff.theMC )
MCIsPlayerEvent (gMovieStuff.theMC,
(const EventRecord *) &macEvent);
} /* end if ( Hwnd2Wptr(hWnd) ) */
switch ( message )
{
case WM_CREATE:
memset (&gMovieStuff, 0, sizeof(MovieStuff));
// Register this HWND with QTML.
CreatePortAssociationEx (hWnd, NULL, kQTMLHandlePortEvents);
gMovieStuff.theHwnd = hWnd;
break;
case WM_INITMENU:
UpdateMenus (gMovieStuff);
break;
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
//Parse the menu selections.
switch ( wmId )
{
case IDM_ABOUT:
DialogBox (hInst,
MAKEINTRESOURCE(IDD_ABOUTBOX),
hWnd,
(DLGPROC)About);
break;
case IDM_EXIT:
CloseMovie (&gMovieStuff);
DestroyPortAssociationEx
( (CGrafPtr)Hwnd2Wptr(hWnd),
kQTMLHandlePortEvents );
DestroyWindow (hWnd);
break;
case IDM_OPEN:
// Close any open movie.
CloseMovie (&gMovieStuff);
// Open a movie file.
if ( GetFile (gMovieStuff.filename) )
{
// Open the movie and size the window.
OpenMovie (hWnd, &gMovieStuff);
// Update the menus.
UpdateMenus (gMovieStuff);
} /* end if */
break;
case IDM_SAVE:
SaveMovie (&gMovieStuff);
UpdateMenus (gMovieStuff);
break;
case IDM_SAVEAS:
SaveAsMovie (&gMovieStuff);
UpdateMenus (gMovieStuff);
break;
case IDM_UNDO:
EditUndo (gMovieStuff.theMC);
break;
case IDM_CUT:
EditCut (gMovieStuff.theMC);
break;
case IDM_COPY:
EditCopy (gMovieStuff.theMC);
break;
case IDM_PASTE:
EditPaste (gMovieStuff.theMC);
break;
case IDM_CLEAR:
EditClear (gMovieStuff.theMC);
break;
case IDM_SELECTALL:
EditSelectAll (gMovieStuff.theMovie,
gMovieStuff.theMC);
break;
default:
return DefWindowProc (hWnd, message,
wParam, lParam);
} /* end switch ( wmId ) */
break;
case WM_PAINT:
hdc = BeginPaint (hWnd, &ps);
// Add any additional drawing code here...
EndPaint (hWnd, &ps);
break;
case WM_CLOSE:
// Unregister the HWND with QTML.
DestroyPortAssociation( (CGrafPtr)Hwnd2Wptr(hWnd) );
break;
case WM_DESTROY:
PostQuitMessage (0);
break;
default:
return DefWindowProc (hWnd, message, wParam, lParam);
} /* end switch ( message ) */
return 0;
} /* end WndProc */
///////////////////////////////////////////////////////////////////////////////////////
//
// About
//
///////////////////////////////////////////////////////////////////////////////////////
LRESULT CALLBACK
About
(HWND hDlg,
UINT message,
WPARAM wParam,
LPARAM lParam)
{
switch (message)
{
case WM_COMMAND:
if ( LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL )
{
EndDialog (hDlg, TRUE);
return TRUE;
} /* end if */
break;
} /* end switch (message) */
return FALSE;
} /* end About */
///////////////////////////////////////////////////////////////////////////////////////
//
// GetFile
//
///////////////////////////////////////////////////////////////////////////////////////
BOOL
GetFile
(char *fileName)
{
OPENFILENAME ofn;
memset (&ofn, 0, sizeof(OPENFILENAME));
fileName[0] = '\0';
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hwndOwner = GetActiveWindow();
ofn.lpstrFile = (LPSTR)fileName;
ofn.nMaxFile = 255;
ofn.lpstrFilter = "QuickTime Movies (*.mov;*.avi)\0*.mov;*.avi\0All Files (*.*)\0*.*\0";
ofn.nFilterIndex = 1;
ofn.lpstrInitialDir = NULL;
if (USEEXPLORERSTYLE)
ofn.Flags |= OFN_ENABLEHOOK | OFN_EXPLORER;
else
ofn.Flags |= OFN_ENABLEHOOK;
ofn.lpfnHook = GenericHook;
if ( GetOpenFileName(&ofn) )
return TRUE;
else
return FALSE;
} /* end GetFile */
///////////////////////////////////////////////////////////////////////////////////////
//
// GenericHook
//
///////////////////////////////////////////////////////////////////////////////////////
static UINT APIENTRY
GenericHook
(HWND hWnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam)
{
switch ( uMsg )
{
case WM_INITDIALOG:
// Center window
{
Point ptTopLeft;
RECT rcWindow;
BOOL retValue;
HWND theWnd = hWnd;
RECT rcDesktopWindow;
long width;
long height;
// If we are using Windows 95 or NT 4.0,
// use the new Explorer style.
if ( USEEXPLORERSTYLE )
theWnd = GetParent(hWnd);
GetWindowRect (theWnd, &rcWindow);
width = rcWindow.right - rcWindow.left;
height = rcWindow.bottom - rcWindow.top;
GetWindowRect (GetDesktopWindow(), &rcDesktopWindow);
ptTopLeft.h = (short)((rcDesktopWindow.right
+ rcDesktopWindow.left) / 2
- width / 2);
ptTopLeft.v = (short)((rcDesktopWindow.top
+ rcDesktopWindow.bottom) / 3
- height / 3);
retValue = SetWindowPos (theWnd,
0,
ptTopLeft.h,
ptTopLeft.v,
0,
0,
SWP_NOZORDER | SWP_NOSIZE);
return TRUE;
} /* end case WM_INITDIALOG */
} /* end switch ( uMsg ) */
return 0;
} /* end GenericHook */
///////////////////////////////////////////////////////////////////////////////////////
//
// OpenMovie
//
///////////////////////////////////////////////////////////////////////////////////////
BOOL
OpenMovie
(HWND hwnd,
MovieStuff *movieStuff)
{
BOOL isMovieGood = FALSE;
if ( strlen( (char*)movieStuff->filename ) != 0 )
{
OSErr err;
short theFile = 0;
long controllerFlags = 0L;
FSSpec sfFile;
short movieResFile;
char theFullPath[255];
// Make a copy of our full pathname.
strcpy (theFullPath, movieStuff->filename);
// Convert to a Pascal string.
c2pstr( (char*)theFullPath );
// Make an FSSpec.
FSMakeFSSpec (0, 0L, theFullPath, &sfFile);
// Set the port.
SetGWorld ( (CGrafPtr)Hwnd2Wptr( (void *)hwnd ), nil);
// Open the movie file.
err = OpenMovieFile (&sfFile, &movieResFile, fsRdPerm);
if (err == noErr)
{
// Get the movie from the file.
err = NewMovieFromFile (&movieStuff->theMovie,
movieResFile,
nil,
nil,
newMovieActive,
nil);
// Close the movie file.
CloseMovieFile (movieResFile);
if (err == noErr)
{
// Create a movie controller.
CreateNewMovieController (hwnd,
movieStuff->theMovie,
&movieStuff->theMC);
// Set flags.
movieStuff->movieOpened = TRUE;
isMovieGood = TRUE;
// Convert pathname back to a C string.
p2cstr ( (char*)theFullPath );
// Set window title.
SetWindowTitle (movieStuff->theHwnd,
theFullPath);
} /* end if (err == noErr) */
else
theFullPath[0] = '\0';
} /* end if (err == noErr) */
else
theFullPath[0] = '\0';
} /* end if ( strlen( (char*)movieStuff->filename ) != 0 ) */
return isMovieGood;
} /* end OpenMovie */
///////////////////////////////////////////////////////////////////////////////////////
//
// CreateNewMovieController
//
///////////////////////////////////////////////////////////////////////////////////////
void
CreateNewMovieController
(HWND hwnd,
Movie theMovie,
MovieController *theMC)
{
Rect bounds;
Rect maxBounds;
long controllerFlags;
Rect theMovieRect;
// 0,0 movie coordinates.
GetMovieBox (theMovie, &theMovieRect);
MacOffsetRect (&theMovieRect, -theMovieRect.left, -theMovieRect.top);
// Attach a movie controller.
*theMC = NewMovieController (theMovie, &theMovieRect, mcTopLeftMovie);
// Get the controller rect.
MCGetControllerBoundsRect (*theMC, &bounds);
// Enable editing.
MCEnableEditing (*theMC, TRUE);
// Tell the controller to attach a movie's CLUT to the window as appropriate.
MCDoAction (*theMC, mcActionGetFlags, &controllerFlags);
MCDoAction (*theMC, mcActionSetFlags,
(void *)(controllerFlags | mcFlagsUseWindowPalette) );
// Allow the controller to accept keyboard events.
MCDoAction (*theMC, mcActionSetKeysEnabled, (void *)TRUE);
// Set the controller action filter.
MCSetActionFilterWithRefCon (*theMC, MCFilter, (long)hwnd);
// Set the grow box amount.
GetMaxBounds (&maxBounds);
MCDoAction (*theMC, mcActionSetGrowBoxBounds, &maxBounds);
// Size our window.
SizeWindow ((WindowPtr)Hwnd2Wptr(hwnd),
bounds.right,
bounds.bottom,
FALSE);
} /* end CreateNewMovieController */
///////////////////////////////////////////////////////////////////////////////////////
//
// MCFilter
//
///////////////////////////////////////////////////////////////////////////////////////
Boolean
MCFilter
(MovieController mc,
short action,
void *params,
long refCon)
{
if ( action == mcActionControllerSizeChanged )
{
Rect bounds;
WindowPtr w;
MCGetControllerBoundsRect (mc, &bounds);
w = Hwnd2Wptr( (HWND)refCon );
SizeWindow ( (WindowPtr)w, bounds.right, bounds.bottom, TRUE );
} /* end if ( action == mcActionControllerSizeChanged ) */
return FALSE;
} /* end MCFilter */
///////////////////////////////////////////////////////////////////////////////////////
//
// GetMaxBounds
//
///////////////////////////////////////////////////////////////////////////////////////
void
GetMaxBounds
(Rect *maxRect)
{
RECT deskRect;
GetWindowRect (GetDesktopWindow(), &deskRect);
OffsetRect (&deskRect, -deskRect.left, -deskRect.top);
maxRect->top = (short)deskRect.top;
maxRect->bottom = (short)deskRect.bottom;
maxRect->left = (short)deskRect.left;
maxRect->right = (short)deskRect.right;
} /* end GetMaxBounds */
///////////////////////////////////////////////////////////////////////////////////////
//
// SetWindowTitle
//
///////////////////////////////////////////////////////////////////////////////////////
void
SetWindowTitle
(HWND hWnd,
unsigned char *theFullPath)
{
unsigned char titleName[256];
titleName[0] = '\0';
GetFileNameFromFullPath ( theFullPath, (unsigned char *)&titleName );
SetWindowText ( hWnd, (const char *)titleName );
} /* end SetWindowTitle */
///////////////////////////////////////////////////////////////////////////////////////
//
// GetFileNameFromFullPath
//
///////////////////////////////////////////////////////////////////////////////////////
void
GetFileNameFromFullPath
(unsigned char *theFullPath,
unsigned char *fileName)
{
int i = 0;
int j = -1;
int stringLen = 0;
stringLen = strlen( (char *)theFullPath );
if ( stringLen > 0 )
{
while ( i < stringLen )
{
if ( theFullPath[i] == 0x5c || theFullPath[i] == '/' )
j = i;
i++;
} /* end while ( i < stringLen ) */
if ( j > -1 )
strcpy ( (char *)fileName, (char *)&theFullPath[j+1] );
else
strcpy ( (char *)fileName, (char *)theFullPath );
} /* end if ( stringLen > 0 ) */
} /* end GetFileNameFromFullPath */
///////////////////////////////////////////////////////////////////////////////////////
//
// CloseMovie
//
///////////////////////////////////////////////////////////////////////////////////////
void
CloseMovie
(MovieStuff *movieStuff)
{
if ( movieStuff->movieOpened )
{
movieStuff->movieOpened = FALSE;
if ( movieStuff->theMC )
DisposeMovieController (movieStuff->theMC);
if ( movieStuff->theMovie )
DisposeMovie (movieStuff->theMovie);
movieStuff->theMovie = NULL;
movieStuff->theMC = NULL;
} /* end if ( movieStuff->movieOpened ) */
} /* end CloseMovie */
///////////////////////////////////////////////////////////////////////////////////////
//
// SaveMovie
//
///////////////////////////////////////////////////////////////////////////////////////
void
SaveMovie
(MovieStuff *movieStuff)
{
OSErr theErr = noErr;
if ( strlen(movieStuff->fileName) != 0 )
{
long movieFlattenFlags = flattenAddMovieToDataFork;
FSSpec sfFile;
OSType creator = OSTypeConst('TVOD');
long createMovieFlags = createMovieFileDeleteCurFile;
char theFullPath[255];
// Make a copy of our full pathname.
strcpy (theFullPath, movieStuff->fileName);
// Convert to a Pascal string.
c2pstr( (char*)theFullPath );
// Make an FSSpec.
FSMakeFSSpec (0, 0L, theFullPath, &sfFile);
// Try to delete the original movie file.
DeleteMovieFile (&sfFile);
// Flatten into a single fork.
FlattenMovie (movieStuff -> theMovie,
movieFlattenFlags,
&sfFile,
creator,
-1,
createMovieFlags,
nil,
NULL);
// Check for error.
theErr = GetMoviesError ();
} /* end if ( strlen(movieStuff->fileName) != 0 ) */
return theErr;
} /* end SaveMovie */
///////////////////////////////////////////////////////////////////////////////////////
//
// SaveAsMovie
//
///////////////////////////////////////////////////////////////////////////////////////
void
SaveAsMovie
(MovieStuff *movieStuff)
{
unsigned char lpszPathName[256];
OPENFILENAME ofn;
OSErr theErr = noErr;
memset (&ofn, 0, sizeof(OPENFILENAME));
lpszPathName[0] = '\0';
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hwndOwner = GetActiveWindow();
ofn.lpstrFile = (LPSTR)lpszPathName;
ofn.nMaxFile = sizeof(lpszPathName);
ofn.lpstrFilter = "QuickTime Movies (*.mov) \0 *.mov\0";
ofn.lpstrFileTitle = NULL;
ofn.nMaxFileTitle = (unsigned long)NULL;
ofn.lpstrInitialDir = NULL;
ofn.Flags = OFN_OVERWRITEPROMPT;
if ( GetSaveFileName (&ofn) )
{
long movieFlattenFlags = flattenAddMovieToDataFork;
FSSpec sfFile;
OSType creator = OSTypeConst('TVOD');
long createMovieFlags = createMovieFileDeleteCurFile;
// Convert pathname to a Pascal string.
c2pstr( (char*)lpszPathName );
// Make an FSSpec.
FSMakeFSSpec (0, 0L, lpszPathName, &sfFile);
// Try to delete the original movie file.
DeleteMovieFile (&sfFile);
// Flatten into a single fork.
FlattenMovie (movieStuff -> theMovie,
movieFlattenFlags,
&sfFile,
creator,
-1,
createMovieFlags,
nil,
NULL);
// Check for error.
theErr = GetMoviesError ();
// Convert pathname back to a C string.
p2cstr( (char*)lpszPathName );
// Set window title.
SetWindowTitle (movieStuff->theHwnd, lpszPathName);
} /* end if ( GetSaveFileName (&ofn) ) */
return theErr;
} /* end SaveAsMovie */
///////////////////////////////////////////////////////////////////////////////////////
//
// EditUndo
//
///////////////////////////////////////////////////////////////////////////////////////
ComponentResult
EditUndo
(MovieController mc)
{
ComponentResult theErr = invalidMovie;
if ( mc )
theErr = MCUndo (mc);
return theErr;
} /* end EditUndo */
///////////////////////////////////////////////////////////////////////////////////////
//
// EditCut
//
///////////////////////////////////////////////////////////////////////////////////////
ComponentResult
EditCut
(MovieController mc)
{
Movie scrapMovie;
ComponentResult theErr = invalidMovie;
if ( mc )
{
scrapMovie = MCCut (mc);
if ( scrapMovie )
{
theErr = PutMovieOnScrap (scrapMovie, 0L);
DisposeMovie (scrapMovie);
} /* end if ( scrapMovie ) */
} /* end if ( mc ) */
return theErr;
} /* end EditCut */
///////////////////////////////////////////////////////////////////////////////////////
//
// EditCopy
//
///////////////////////////////////////////////////////////////////////////////////////
ComponentResult
EditCopy
(MovieController mc)
{
Movie scrapMovie;
ComponentResult theErr = invalidMovie;
if ( mc )
{
scrapMovie = MCCopy (mc);
if ( scrapMovie )
{
theErr = PutMovieOnScrap (scrapMovie, 0L);
DisposeMovie (scrapMovie);
} /* end if ( scrapMovie ) */
} /* end if ( mc ) */
return theErr;
} /* end EditCopy */
///////////////////////////////////////////////////////////////////////////////////////
//
// EditPaste
//
///////////////////////////////////////////////////////////////////////////////////////
ComponentResult
EditPaste
(MovieController mc)
{
ComponentResult theErr = invalidMovie;
if ( mc )
theErr = MCPaste (mc, nil);
return theErr;
} /* end EditPaste */
///////////////////////////////////////////////////////////////////////////////////////
//
// EditClear
//
///////////////////////////////////////////////////////////////////////////////////////
ComponentResult
EditClear
(MovieController mc)
{
ComponentResult theErr = invalidMovie;
if ( mc )
theErr = MCClear (mc);
return theErr;
} /* end EditClear */
///////////////////////////////////////////////////////////////////////////////////////
//
// EditSelectAll
//
///////////////////////////////////////////////////////////////////////////////////////
ComponentResult
EditSelectAll
(Movie movie,
MovieController mc)
{
TimeRecord tr;
ComponentResult theErr = noErr;
if ( movie && mc )
{
tr.value.hi = 0;
tr.value.lo = 0;
tr.base = 0;
tr.scale = GetMovieTimeScale(movie);
MCDoAction (mc, mcActionSetSelectionBegin, &tr);
tr.value.lo = GetMovieDuration(movie);
MCDoAction (mc, mcActionSetSelectionDuration, &tr);
} /* end if ( movie && mc ) */
else
{
if ( movie == NULL )
theErr = invalidMovie;
else
theErr = -1;
} /* end else */
return theErr;
} /* end EditSelectAll */
///////////////////////////////////////////////////////////////////////////////////////
//
// UpdateMenus
//
///////////////////////////////////////////////////////////////////////////////////////
void
UpdateMenus
(MovieStuff movieStuff)
{
HMENU hMenu = GetMenu(movieStuff.theHwnd);
if ( !hMenu )
return;
if ( movieStuff.movieOpened )
{
EnableMenuItem (hMenu, IDM_SAVE, MF_ENABLED);
EnableMenuItem (hMenu, IDM_SAVEAS, MF_ENABLED);
EnableMenuItem (hMenu, IDM_UNDO, MF_ENABLED);
EnableMenuItem (hMenu, IDM_CUT, MF_ENABLED);
EnableMenuItem (hMenu, IDM_COPY, MF_ENABLED);
EnableMenuItem (hMenu, IDM_PASTE, MF_ENABLED);
EnableMenuItem (hMenu, IDM_CLEAR, MF_ENABLED);
EnableMenuItem (hMenu, IDM_SELECTALL, MF_ENABLED);
} /* end if ( movieStuff.movieOpened ) */
else
{
EnableMenuItem (hMenu, IDM_SAVE, MF_GRAYED);
EnableMenuItem (hMenu, IDM_SAVEAS, MF_GRAYED);
EnableMenuItem (hMenu, IDM_UNDO, MF_GRAYED);
EnableMenuItem (hMenu, IDM_CUT, MF_GRAYED);
EnableMenuItem (hMenu, IDM_COPY, MF_GRAYED);
EnableMenuItem (hMenu, IDM_PASTE, MF_GRAYED);
EnableMenuItem (hMenu, IDM_CLEAR, MF_GRAYED);
EnableMenuItem (hMenu, IDM_SELECTALL, MF_GRAYED);
} /* end else */
} /* end UpdateMenus */
| Previous | Chapter Contents | Chapter Top | Roadmap |